package routers

import (
	"fmt"
	"log"
	"path/filepath"

	"github.com/atcharles/wslt"
	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/gzip"
	"github.com/gin-gonic/gin"

	"gitee.com/goframe/lt-collector/common"
	"gitee.com/goframe/lt-collector/common/push_client"
	"gitee.com/goframe/lt-collector/handler"
	"gitee.com/goframe/lt-collector/libs/abio"
	"gitee.com/goframe/lt-collector/libs/libgin"
	"gitee.com/goframe/lt-collector/libs/pool"
	"gitee.com/goframe/lt-collector/model"
)

//GinServer ...
func GinServer() {
	gin.SetMode(gin.ReleaseMode)
	gin.DisableConsoleColor()
	router := NewRouter(gin.New())
	api := router.API()
	router.Manager(api)
	//add api ...
	log.Fatalln(router.Engine.Run(fmt.Sprintf(":%s", common.DefConf.Web.Listen)))
}

type (
	Router struct {
		*gin.Engine
		webOut, webErr *abio.AbFile
	}
)

func NewRouter(engine *gin.Engine) *Router {
	logOut := abio.NewAbFile(filepath.Join(abio.SelfDir(), "logs", "web", "web.log"), nil)
	errOut := abio.NewAbFile(filepath.Join(abio.SelfDir(), "logs", "web", "err.log"), nil)
	gin.DefaultWriter = logOut
	//gzip压缩
	engine.Use(gzip.Gzip(6))
	//设置错误输出
	pool.DefRec.SetOut(errOut)
	engine.Use(gin.RecoveryWithWriter(errOut))
	engine.Use(gin.LoggerWithWriter(logOut))
	config := cors.DefaultConfig()
	config.AllowAllOrigins = true
	config.AddAllowHeaders("Authorization", "Accept-Encoding", "X-Request-ID")
	engine.Use(cors.New(config)) //cors
	//root router
	{
		engine.GET("/", func(c *gin.Context) {
			c.JSON(200, gin.H{"status": "OK", "name": common.Server, "version": common.Version,
				"information": "Welcome Lotto开奖API!"})
		})
		wslt.StdLogger.SetOutput(errOut)
		engine.GET("/ws", gin.WrapF(wslt.New().Handler(new(handler.WsUser))))
		handler.ConnectorHandler.Handle()
		//错误中间件
		engine.Use(libgin.Return.MiddlewareErr)
		engine.GET("/sids/:uid", handler.WsUser{}.Sids())
		engine.GET("/pull/call", push_client.PullHandler())
	}
	return &Router{
		Engine: engine,
		webOut: logOut,
		webErr: errOut,
	}
}

func (r *Router) API() *gin.RouterGroup {
	api := r.Engine.Group("/API")
	//before auth
	api.GET("/ClearCache", handler.SetHandler.ClearCache())
	api.POST("/Login", model.Auth{}.Login())
	//user auth check
	api.Use(libgin.Return.WarpHandler(model.Auth{}.Auth))
	//pull
	api.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{"pong": "ok"})
	})
	api.PUT("/ChangePassword", model.Auth{}.ChangePassword())
	api.GET("/OpenInfo/:gid", libgin.Return.WarpHandler(handler.GameHandler.OpenInfo()))
	return api
}

func (r *Router) Manager(api *gin.RouterGroup) *gin.RouterGroup {
	manager := api.Group("/Manager", libgin.Return.WarpHandler(model.Auth{}.Manager))
	manager.POST("/AddUser", model.Auth{}.AddUser())
	manager.POST("/ResetPassword/:uid", model.Auth{}.ResetPassword())
	//资源类型
	manager.GET("/Sources", handler.Game{}.GetSources())
	//彩种类型
	manager.GET("/LtTypes", libgin.NewRequest(model.GameTypes{}))
	//采集资源
	manager.Any("/CollectSource", libgin.NewRequest(model.GameCollectSource{}))
	//添加彩种
	manager.POST("/AddLotto", libgin.Return.WarpHandler(handler.GameHandler.AddLotto()))
	manager.Any("/Lotto", libgin.NewRequest(model.GameLotteries{}))
	//彩种计划
	manager.Any("/GamePlan", libgin.NewRequest(model.GameIssuePlan{}))
	//开采网参数,168参数
	manager.Any("/SourceParamKcw", libgin.NewRequest(model.GameSourceParamKcw{}))
	manager.Any("/SourceParam168", libgin.NewRequest(model.GameSourceParam168{}))
	manager.Any("/SourceByCollector", libgin.NewRequest(model.ByCollector{}))
	manager.Any("/SourceTxFFC", libgin.NewRequest(model.TXCollector{}))
	//系统参数
	manager.PUT("/Setting", handler.SetHandler.PUT())
	manager.Any("/SysSetting", libgin.NewRequest(model.SysSetting{}))
	//开奖历史
	manager.GET("/History", libgin.NewRequest(model.OpenData{}))
	//开奖时间表
	manager.GET("/TimeList/:gid", handler.GameHandler.OpenTimeList())
	//用户列表
	manager.GET("/Users", libgin.NewRequest(model.User{}))
	//重启服务
	manager.POST("/Reboot", handler.SetHandler.Reboot())
	//期号校对
	manager.Any("/IssueCheck", libgin.NewRequest(model.GameIssueCheck{}))
	return manager
}
